﻿using System;
using System.Collections.Generic;
using GeoAPI.Geometries;
using YJKGridTopologyCal.Utilities;

namespace YJKGridTopologyCal.Planargraph
{
	public class DirectedEdgeStar
	{
		public void Add(DirectedEdge de)
		{
			this._outEdges.Add(de);
			this._sorted = false;
		}

		public void Remove(DirectedEdge de)
		{
			this._outEdges.Remove(de);
		}

		public IEnumerator<DirectedEdge> GetEnumerator()
		{
			this.SortEdges();
			return this._outEdges.GetEnumerator();
		}

		public int Degree
		{
			get
			{
				return this._outEdges.Count;
			}
		}

		public Coordinate Coordinate
		{
			get
			{
				if (this._outEdges.Count == 0 || this._outEdges[0] == null)
				{
					return null;
				}
				return this._outEdges[0].Coordinate;
			}
		}

		public IList<DirectedEdge> Edges
		{
			get
			{
				this.SortEdges();
				return this._outEdges;
			}
		}

		private void SortEdges()
		{
			if (!this._sorted)
			{
				List<DirectedEdge> collection = new List<DirectedEdge>(CollectionUtil.StableSort<DirectedEdge>(this._outEdges));
				this._outEdges.Clear();
				this._outEdges.AddRange(collection);
				this._sorted = true;
			}
		}

		public int GetIndex(Edge edge)
		{
			this.SortEdges();
			for (int i = 0; i < this._outEdges.Count; i++)
			{
				if (this._outEdges[i].Edge == edge)
				{
					return i;
				}
			}
			return -1;
		}

		public int GetIndex(DirectedEdge dirEdge)
		{
			this.SortEdges();
			for (int i = 0; i < this._outEdges.Count; i++)
			{
				if (this._outEdges[i] == dirEdge)
				{
					return i;
				}
			}
			return -1;
		}

		public int GetIndex(int i)
		{
			int num = i % this._outEdges.Count;
			if (num < 0)
			{
				num += this._outEdges.Count;
			}
			return num;
		}

		public DirectedEdge GetNextEdge(DirectedEdge dirEdge)
		{
			int index = this.GetIndex(dirEdge);
			return this._outEdges[this.GetIndex(index + 1)];
		}

		public DirectedEdge GetNextCWEdge(DirectedEdge dirEdge)
		{
			int index = this.GetIndex(dirEdge);
			return this._outEdges[this.GetIndex(index - 1)];
		}

		private readonly List<DirectedEdge> _outEdges = new List<DirectedEdge>();

		private bool _sorted;
	}
}
